home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Java 1996 August
/
Java - Summer 1996.iso
/
kaffe-0.2
/
kaffe
/
locks.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-11
|
3KB
|
158 lines
/*
* locks.c
* Manage locking system
* This include the mutex's and cv's.
*
* Copyright (c) 1996 Systems Architecture Research Centre,
* City University, London, UK.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* Written by Tim Wilkinson <tim@sarc.city.ac.uk>, February 1996.
*/
#include <assert.h>
#include "object.h"
#include "baseClasses.h"
#include "thread.h"
#include "locks.h"
#include "errors.h"
/*
* Lock a mutex.
*/
void
lockMutex(object* obj)
{
intsDisable();
if (obj->holder == 0) {
obj->holder = currentThread;
obj->count = 1;
}
else if (obj->holder == currentThread) {
obj->count++;
}
else {
while (obj->holder != 0) {
suspendOnQThread(currentThread, &obj->muxWaiters);
}
obj->holder = currentThread;
obj->count = 1;
}
intsRestore();
}
/*
* Release a mutex.
*/
void
unlockMutex(object* obj)
{
thread* tid;
intsDisable();
assert(obj->holder == currentThread);
obj->count--;
if (obj->count == 0) {
obj->holder = 0;
if (obj->muxWaiters != 0) {
tid = obj->muxWaiters;
obj->muxWaiters = tid->next;
resumeThread(tid);
}
}
intsRestore();
}
/*
* Wait on a conditional variable.
* (timeout currently ignored)
*/
void
waitCond(object* obj, long long timeout)
{
int count;
if (obj->holder != currentThread) {
throwException(IllegalMonitorStateException);
}
intsDisable();
count = obj->count;
obj->holder = 0;
obj->count = 0;
/* Suspend, and keep suspended until I re-get the lock */
suspendOnQThread(currentThread, &obj->cvWaiters);
while (obj->holder != 0) {
suspendOnQThread(currentThread, &obj->muxWaiters);
}
obj->holder = currentThread;
obj->count = count;
intsRestore();
}
/*
* Wake one thread on a conditional variable.
*/
void
signalCond(object* obj)
{
thread* tid;
if (obj->holder != currentThread) {
throwException(IllegalMonitorStateException);
}
intsDisable();
/* Remove one thread from cv list */
if (obj->cvWaiters != 0) {
tid = obj->cvWaiters;
obj->cvWaiters = tid->next;
/* Place it on mux list */
tid->next = obj->muxWaiters;
obj->muxWaiters = tid;
}
intsRestore();
}
/*
* Wake all threads on a conditional variable.
*/
void
broadcastCond(object* obj)
{
thread** tidp;
if (obj->holder != currentThread) {
throwException(IllegalMonitorStateException);
}
intsDisable();
/* Find the end of the cv list */
if (obj->cvWaiters) {
for (tidp = &obj->cvWaiters; *tidp != 0; tidp = &(*tidp)->next)
;
/* Place entire cv list on mux list */
(*tidp) = obj->muxWaiters;
obj->muxWaiters = obj->cvWaiters;
obj->cvWaiters = 0;
}
intsRestore();
}